package com.xiaofan.orientobject

import scala.util.Random

object 模式匹配07 {
  def main(args: Array[String]): Unit = {
    // Scala有一个十分强大的模式匹配机制，可以应用到很多场合：如switch语句、类型检查等。并且Scala还提供了样例类，对模式匹配进行了优化，可以快速进行匹配
  }
}

// 匹配字符串
/**
 * 应用程序对象： Scala程序都必须从一个对象的main方法开始，可以通过扩展App特质，不写main方法。
 */
object CaseDemo1 extends App {
  val arr = Array("Hadoop", "Storm", "Spark")
  val item = arr(Random.nextInt(arr.length))

  item match {
    case "Hadoop" => println("Hadoop")
    case "Storm" => println("Storm")
    case _ => println("default .. Spark")
  }
}

// 匹配类型
/**
 * 应用程序对象： Scala程序都必须从一个对象的main方法开始，可以通过扩展App特质，不写main方法。
 */
object CaseDemo2 extends App {
  val arr = Array("hello", 1, -2.0, CaseDemo2)
  val elem = arr(Random.nextInt(arr.length))

  println(elem)

  elem match{
    case x: Int => println("Int " + x)
    case y: Double if(y >=0) => println("Double " + y)
    case z: String => println("String " + z)
    case CaseDemo2 => {
      println("case demo 2")
    }
    case _ => println("not match..")
  }

  // 注意：case y: Double if(y >= 0) => ...
  // 模式匹配的时候还可以添加守卫条件。如不符合守卫条件，将掉入case _中
}

// 匹配数组、元组

/**
 * 应用程序对象： Scala程序都必须从一个对象的main方法开始，可以通过扩展App特质，不写main方法。
 */
object CaseDemo3 extends App {
  val arr = Array(1,5,7,0)
  arr match {
    case Array(1,5,x,y) => println(x + " " + y)
    case Array(1,5,7,y) => println(y)
    case Array(0, _*) => println("0 ...")
    case _ => println("Something else ...")
  }
}
// 注意： 匹配的过程中只要找到就不再继续往下找了


/**
 * 应用程序对象： Scala程序都必须从一个对象的main方法开始，可以通过扩展App特质，不写main方法。
 */
object CaseDemo4 extends App {
  val lst = List(1,2,3,4,5)
  println(lst.head)
  println(lst.tail)

  lst match {
    case 0 :: Nil => println("only 0")
    case x :: y :: Nil => println(s"x $x y $y")
    case 1 :: a => println(s"1 ... $a")
    case _ => println("something else ...")
  }
}

// 运行结果：
// 1
// List(2, 3, 4, 5)
// 1...List(2, 3, 4, 5)

// 注意：
// 在Scala中列表要么为空（Nil表示空列表）要么是一个head元素加上一个tail列表。
// 9 :: List(5, 2)  :: 操作符是将给定的头和尾创建一个新的列表
// :: 操作符是右结合的，如9 :: 5 :: 2 :: Nil相当于 9 :: (5 :: (2 :: Nil))

/**
 * 应用程序对象： Scala程序都必须从一个对象的main方法开始，可以通过扩展App特质，不写main方法。
 */
object CaseDemo5 extends App {
  val tup = (1, 3, 5)
  tup match {
    case (1, x, y) => println(s"hello 123 $x , $y")
    case (_, z, 5) => println(z)
    case _ => println("Something else")
  }
}

// 注意：特殊的下划线 _ 的作用
